__DefBitFieldType IExt<1>
    NoX = 0x0;
    X = 0x1;

__DefBitFieldType I8Type<1>
    S8 = 0x0;
    U8 = 0x1;

__DefBitFieldType I16Type<1>
    S16 = 0x0;
    U16 = 0x1;

__DefBitFieldType IType<1>
    S32 = 0x0;
    U32;

__DefBitFieldType IXType<1>
    S64;
    U64;

__DefBitFieldType LEASX32<1>
    NoSX32;
    SX32;

__DefBitFieldType BSel<2>
    B0;
    B1;
    B2;
    B3;

__DefBitFieldType CWMode<1>
    C; // CLAMP
    W; // WRAP

__DefBitFieldType LOHI<1>
    LO;
    HI;

__DefBitFieldType CompOp<3>
    EQ;
    NE;
    LT;
    LE;
    GT;
    GE;

__DefBitFieldType BoolOp<2>
//  NoBop;
    AND;
    OR;
    XOR;

__DefBitFieldType BMBF<1>
    BM;
    BF;

__DefBitFieldType EXBool<2>
    PAND;
    POR;

__DefBitFieldType SHFDType<2>
    S64;
    U64;
    S32;
    U32;

__DefBitFieldType PRMTMode<3>
  IDX;
  F4E;
  B4E;
  RC8;
  ECL;
  ECR;
  RC16;

__DefBitFieldType I2IDType<2>
  S8;
  U8;
  S16;
  U16;

__DefBitFieldType SATRelu<1>
  SAT;
  SATRELU;

__DefBitFieldType I2IPDType<3>
  S2;
  U2;
  S4;
  U4;
  S8;
  U8;
  S16;
  U16;

__DefBitFieldType SHFDir<1>
    L;
    R;

__DefBitFieldType MOVW<1>
    32;
    64;

__DefGroup IALU : [ALL]
  __Encoding
    field<12,  3> Pred pg = PT;
    field<15,  1> PModi pg.not = False;

__DefOptype IADD : [IALU]
  __Encoding
    field<0,  8> Optype optype == IADD;
    field<16,  8> Reg rd;

    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;

    field<76,  1> IExt ext = NoX;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<106, 3> Pred pu = PT;

  __Syntax
```asm
IADD   Rd,       {-}Ra, {-}SrcB          $sched $req ;
IADD.X Rd{ ,pu}, {-}Ra, {-}SrcB{, {!}pp} $sched $req ;
```
  __Description
进行整数加法，即Rd = Ra + SrcB。

加法是对输入整数的二进制补码进行的，因此不区分有无符号。

  __OperandInfo
    AsmFormat<ra.neg> = CvtINegX(ra.neg, ext);

输出操作数Rd和输入操作数Ra必须来源于GPR。

输入操作数SrcB的来源可以是GPR、UR、Imm32或cmem。

Ra和SrcB都可以添加一个负号(-)前缀，表示取来源的相反数作为操作数。

启用.X修饰符后，需要额外2个操作数pu和pp，分别表示输出进位和输入进位：
| pu | pp |
|:--:|:--:|
| PR | PR |

操作数pp可以选择添加一个逻辑非(!)前缀，表示取反作为操作数。

pu的默认值是PT，pp的默认值是!PT，二者取默认值时均可省略。

在启用.X修饰符后，操作数Ra、SrcB的可选前缀只能是按位取反(~)，不能是负号(-)。

  __ModifierInfo
.X修饰符表示带有输入/输出进位的扩展位宽加法，接受一个额外的进位输入，产生一个额外的进位输出。

  __Semantics
```asm
// 32bit整数加法
IADD Rd, Ra, SrcB:
    t = Ra + SrcB;
    Rd = t[31:0];

// 带输入/输出进位的扩展位宽加法
IADD.X Rd, pu, Ra, SrcB, pp:
    t = Ra + SrcB + pp;
    // 4294967296 = 2^32 = 0x100000000
    Rd = mod(t, 4294967296);
    pu = t > 4294967296 ? true : false;
```
  __Examples
```asm
IADD R0, R1,        R2 ; // R0 = R1 + R2
IADD R0, R1,       -R2 ; // R0 = R1 - R2
IADD R0, R1, -0x114514 ; // R0 = R1 - 0x114514

IADD.X R0, P0, R2, -R4     ;
IADD.X R1, PT, R3, ~R5, P0 ; // 联合完成R[0:1]=R[2:3]+(-R[4:5])的64bit加法
```

__DefOpcode IADD_RR : [IADD]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
    field<97,  1> SignModi rb.neg = False;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;
    AsmFormat<rb.neg> = CvtINegX(rb.neg, ext);

__DefOpcode IADD_RU : [IADD]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
    field<97,  1> SignModi urb.neg = False;

  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, urb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;
    AsmFormat<urb.neg> = CvtINegX(urb.neg, ext);

__DefOpcode IADD_RI : [IADD]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IADD_RC : [IADD]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
    field<97,  1> SignModi vb.neg = False;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;
    AsmFormat<vb.neg> = CvtINegX(vb.neg, ext);

__DefOptype IMAD : [IALU]
  __Encoding
    field<0,   8> Optype optype == IMAD;
    field<16,  8> Reg rd;

    field<24,  8> Reg ra;

    field<75,  1> LOHI lohi = LO;
    field<76,  1> IExt ext = NoX;
    field<77,  1> IType itype = S32;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<106, 3> Pred pu = PT;

  __Syntax
```asm
IMAD{.LO}{.itype} Rd{, pu}, Ra, SrcB, {-}SrcC               $sched $req ; // 低32bit模式
IMAD.HI.X{.itype} Rd{, pu}, Ra, SrcB, {-}SrcC{, {!}pp}      $sched $req ; // 扩展位宽模式

.itype = {.S32*, .U32}
```
  
  __Description
进行整数乘加运算，即Rd = Ra * SrcB + SrcC。

视启用的修饰符的不同，有2种不同的模式：
- 低32bit模式：启用.LO修饰符，Rd = Ra * SrcB + SrcC，输出进位pu。
- 扩展位宽模式：启用.HI.X修饰符，Rd = (Ra * SrcB) >> 32 + SrcC + pp。

每一种模式的准确语义请参考Semantics部分。

  __OperandInfo
操作数Rd和Ra必须来源于GPR。

操作数SrcB和SrcC的合法来源组合如下：

| SrcB | SrcC |
|:--:|:--:|
| GPR | GPR |
| GPR | Imm32 |
| Imm32 | GPR |
| GPR |cmem |
|cmem | GPR |
| GPR | UR  |
| UR  | GPR |

启用.LO修饰符时，操作数SrcC可以选择添加一个负号(-)前缀，表示取相反数作为操作数。

启用.HI和.X修饰符时，操作数SrcC可以选择添加按位取反(~)前缀，表示对SrcC按位取反作为操作数。

2个谓词操作数pu和pp，分别表示输出进位和输入进位：

| pu | pp |
|:--:|:--:|
| PR | PR |

操作数pp可以选择添加一个逻辑非(!)前缀，表示取反作为操作数。

pu的默认值是PT，pp的默认值是!PT，二者取默认值时均可省略。

  __ModifierInfo
启用.LO修饰符时（默认可省略），表示取Ra*SrcB乘积的低32bit（以二进制补码的形式）与SrcC相加，结果写入Rd，并输出进位pu。

启用.HI和.X修饰符时，表示取Ra*SrcB乘积的高32bit（以二进制补码的形式）与SrcC和输入进位pp相加，结果写入Rd。

.itype可取值.S32（默认，可省略）或.U32，分别表示将Ra和SrcB视为有符号数或无符号数进行乘法。

  __Semantics
```asm
// 低32bit模式
IMAD.LO.itype Rd, pu, Ra, SrcB, SrcC:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = a * b;
    // 4294967296 = 2^32 = 0x100000000
    Rd = mod(t[31:0] + SrcC, 4294967296);
    pu = t[31:0] + SrcC > 4294967296 ? true : false;

// 扩展位宽模式
IMAD.HI.X.itype Rd, pu, Ra, SrcB, SrcC, pp:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = a * b;
    // 4294967296 = 2^32 = 0x100000000
    Rd = mod(t[63:32] + SrcC + pp, 4294967296);
    pu = t[63:32] + SrcC + pp > 4294967296 ? true : false;
```

  __Examples
```asm
IMAD R0, R1, R2, R3;    // R0 = R1 * R2 + R3

IMAD.U32      R0, P0, R2, 0x114514, R4,   ;
IMAD.HI.X.U32 R1,     R2, 0x114514, R5, P0; // 联合完成R[0:1] = R2 * 0x114514 + R[4:5]的64bit乘加

IMAD      R0, P0, R2, R3, -R4    ;
IMAD.HI.X R1,     R2, R3, ~R5, P0; // 联合完成R[0:1] = R2 * R3 - R[4:5]的64bit乘加
```

__DefOpcode IMAD_RRR : [IMAD]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;

    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, rb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, rc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOpcode IMAD_RRI : [IMAD]
  __Encoding
    field<8,   4> SType stype == RRI;
    field<32, 32> SImm32 vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;

__DefOpcode IMAD_RIR : [IMAD]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOpcode IMAD_RRC : [IMAD]
  __Encoding
    field<8,   4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<97,  1> SignModi vc.neg = False;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    AsmFormat<vc.neg> = CvtINegX(vc.neg, ext);

__DefOpcode IMAD_RCR : [IMAD]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOpcode IMAD_RRU : [IMAD]
  __Encoding
    field<8,   4> SType stype == RRU;
    field<32,  6> UReg urc;
    field<97,  1> SignModi urc.neg = False;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, urc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, urc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 32;
    AsmFormat<urc.neg> = CvtINegX(urc.neg, ext);

__DefOpcode IMAD_RUR : [IMAD]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, urb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, urb, rc, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOptype IMAD_WIDE : [IALU]
  __Encoding
    field<0,  8> Optype optype == IMAD_WIDE;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<76,  1> IExt ext = NoX;
    field<77,  1> IType itype = S32;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<106, 3> Pred pu = PT;

  __Syntax
```asm
IMAD.WIDE.itype   Rd{, pu}, Ra, SrcB, {-}SrcC               $sched $req ;   // 64bit模式
IMAD.WIDE.X.itype Rd{, pu}, Ra, SrcB, {-}SrcC{, {!}pp}      $sched $req ;   // 扩展位宽模式

.itype = {.S32*, .U32}
```

  __Description
进行64bit整数乘加运算，即Rd = Ra * SrcB + SrcC，其中Ra和SrcB都是32bit整数，Rd和SrcC都是64bit整数。
先计算32bit整数乘法，乘积再进行64bit整数加法。

  __OperandInfo
操作数Rd和Ra必须来源于GPR。

操作数SrcB和SrcC的合法来源组合如下：

| SrcB | SrcC |
|:--:|:--:|
| GPR | GPR |
| Imm32 | GPR |
| GPR | cmem|
|cmem | GPR |
| GPR | UR  |
| UR  | GPR |

操作数SrcC可以选择添加一个负号(-)前缀，表示取相反数作为操作数。但在启用.X修饰符后，SrcC的可选前缀只能是按位取反(~)，不能是负号(-)。

Rd和SrcC必须是64bit整数操作数。
关于如何表示大于32bit位宽的寄存器操作数，请参考[扩展位宽的寄存器操作数](操作数汇编显示规则.md#扩展位宽的寄存器操作数)。

输入谓词操作数pp的默认值是!PT（此时可省略），可以选择添加一个逻辑非(!)前缀，表示取反作为操作数。

输出谓词操作数pu的默认值是PT（此时可省略）。

  __ModifierInfo
.itype可取值.S32（默认，可省略）或.U32，分别表示将Ra和SrcB视为有符号数或无符号数进行乘法计算。

启用.X修饰符表示进行带输入/输出进位的扩展位宽加法，即Rd = Ra*SrcB + SrcC + pp，并输出进位pu。

  __Semantics
```asm
// 64bit模式
IMAD.WIDE.itype Rd, pu, Ra, SrcB, SrcC:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = a * b;
    Rd = mod(t + SrcC, 1<<64);
    pu = t + SrcC > (1<<64) ? true : false;

// 扩展位宽模式
IMAD.WIDE.X.itype Rd, pu, Ra, SrcB, SrcC, pp:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = a * b;
    Rd = mod(t + SrcC + pp, 1<<64);
    pu = t + SrcC + pp > (1<<64) ? true : false;
```

  __Examples
```asm
IMAD.WIDE     R[0:1], R2,       R3,  R[4:5];
IMAD.WIDE.U32 R[0:1], R7, 0x114514, -R[4:5];

IMAD.WIDE.X R[0:1], P0, R4, R5, R[6:7]     ;
IMAD.WIDE.X R[2:3],     RZ, RZ,     RZ,  P0; // 联合完成R[0:3]=R4*R5+R[6:7]的乘加（结果保留到128bit）
```

__DefOpcode IMAD_WIDE_RRR : [IMAD_WIDE]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, rb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, rc, pp>;
    Bitwidth<rd> = 64;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 64;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOpcode IMAD_WIDE_RIR : [IMAD_WIDE]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<rd> = 64;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 64;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOpcode IMAD_WIDE_RRC : [IMAD_WIDE]
  __Encoding
    field<8,   4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<97,  1> SignModi vc.neg = False;

    field<64,  8> Reg rb;
  __OperandInfo

    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<rd> = 64;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 64;
    AsmFormat<vc.neg> = CvtINegX(vc.neg, ext);

__DefOpcode IMAD_WIDE_RCR : [IMAD_WIDE]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;

    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo

    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, vb, rc, pp>;
    Bitwidth<rd> = 64;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 64;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOpcode IMAD_WIDE_RRU : [IMAD_WIDE]
  __Encoding
    field<8,   4> SType stype == RRU;
    field<32,  6> UReg urc;
    field<97,  1> SignModi urc.neg = False;

    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, urc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, urc, pp>;
    Bitwidth<rd> = 64;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 64;
    AsmFormat<urc.neg> = CvtINegX(urc.neg, ext);

__DefOpcode IMAD_WIDE_RUR : [IMAD_WIDE]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;

    field<64,  8> Reg rc;
    field<74,  1> SignModi rc.neg = False;
  __OperandInfo
    InList<pg, ra, urb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, urb, rc, pp>;
    Bitwidth<rd> = 64;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 64;
    AsmFormat<rc.neg> = CvtINegX(rc.neg, ext);

__DefOptype IDP2A : [IALU]
  __Encoding
    field<0,  8> Optype optype == IDP2A;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<75,  1> LOHI lohi = LO;
    field<77,  1> I16Type afmt;
    field<78,  1> I8Type bfmt;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<106, 3> Pred pu = PT;

  __Syntax
```asm          
IDP.2A{.lohi}.afmt.bfmt Rd{, pu}, Ra, SrcB, SrcC{, {!}pp}      $sched $req ;

.lohi = {.LO*, .HI}
.afmt = {.S16, .U16}
.bfmt = {.S8, .U8}
```

  __Description
对2个二维整数向量计算内积，结果与一个整数标量相加后输出。

  __OperandInfo
操作数Rd和Ra必须来源于GPR。

操作数SrcB和SrcC的合法来源组合如下：

| SrcB | SrcC |
|:--:|:--:|
| GPR | GPR |
| GPR  | Imm32 |
| Imm32 | GPR |
| GPR | cmem|
| cmem| GPR |
| GPR | UR |

操作数pu和pp用于表示扩展位宽加法中的输出/输入进位，只能来源于PR，其中输出操作数pu的默认值为PT，可省略。

操作数pp可以添加一个逻辑非(!)前缀，表示取反作为操作数。pp的默认值是!PT，此时可以省略。

  __ModifierInfo
.lohi可取值为.LO（默认值，可省略）和.HO，分别表示选取操作数SrcB的低16bit或高16bit参与运算。

.afmt可取.S16或.U16，表示操作数Ra存储的二维整数向量的元素是有符号16bit数还是无符号16bit数。

.bfmt可取.S8或.U8，表示操作数SrcB存储的二维整数向量的元素是有符号8bit数还是无符号8bit数。

.afmt必须位于.bfmt之前。

  __Semantics
```asm
IDP.2A.lohi.afmt.bfmt Rd, pu, Ra, SrcB, SrcC, pp:
    d = SrcC + pp;
    // 根据.afmt，将Ra的2个连续16bit进行符号扩展/零扩展到32bit，得到整数向量va
    // va[0]是低16位的扩展结果，va[1]是高16位的扩展结果
    va = extractAndExtendPacked16bit(Ra, .afmt);
    // 根据.bfmt，将SrcB的4个连续8bit进行符号扩展/零扩展到32bit，得到整数向量vb
    // vb[0]是最低字节的结果，vb[3]是最高字节的结果，以此类推
    vb = extractAndExtendPacked8bit(SrcB, .bfmt);
    // 根据.lohi，选取vb的前2个元素或后两个元素进行运算
    b_select = (.lohi == .LO) ? 0 : 2;
    for (i = 0; i < 2; i++) {
        d += va[i] * vb[b_select + i];
    }
    // 4294967296 = 2^32 = 0x100000000
    pu = ceil(d / 4294967296) > 0 ? true : false;
    Rd = mod(d, 4294967296);
```

  __Examples
```asm
IDP.2A.U16.S8 R0, R1,         R2, 0x0;
IDP.2A.S16.S8 R0, R1, 0xAABBCCDD,  R3;
```

__DefOpcode IDP2A_RRR : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP2A_RRI : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RRI;
    field<32, 32> SImm32 vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP2A_RIR : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP2A_RRC : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP2A_RCR : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP2A_RRU : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RRU;
    field<32,  6> UReg urc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, urc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, urc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP2A_RUR : [IDP2A]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, urb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, urb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOptype IDP4A : [IALU]
  __Encoding
    field<0,  8> Optype optype == IDP4A;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<77,  1> I8Type afmt;  // TODO: order
    field<78,  1> I8Type bfmt;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<106, 3> Pred pu = PT;

  __Syntax
```asm          
IDP.4A.afmt.bfmt Rd{,pu}, Ra, SrcB, SrcC{,{!}pp}      $sched $req ;

.afmt = {.S8, .U8}
.bfmt = {.S8, .U8}
```

  __Description
对2个四维整数向量计算内积，结果与一个整数标量相加后输出。

  __OperandInfo
    ModiOrder<afmt, bfmt>;

操作数Rd和Ra必须来源于GPR。

操作数SrcB和SrcC的合法来源组合如下：

| SrcB | SrcC |
|:--:|:--:|
| GPR | GPR |
| GPR  | Imm32 |
| Imm32 | GPR |
| GPR | cmem|
| cmem| GPR |
| GPR | UR |

操作数pu和pp用于表示扩展位宽加法中的输出/输入进位，只能来源于PR，其中输出操作数pu的默认值为PT，可省略。

操作数pp可以添加一个逻辑非(!)前缀，表示取反作为操作数。pp的默认值是!PT，此时可以省略。

  __ModifierInfo
.afmt和.bfmt的可取值包括.S8或.U8，表示操作数Ra/SrcB中存储的四维整数向量的元素是有符号8bit数还是无符号8bit数。

.afmt必须位于.bfmt之前。

  __Semantics
```asm
IDP.4A.afmt.bfmt Rd, pu, Ra, SrcB, SrcC, pp:
    d = SrcC + pp;
    // 根据.afmt，将Ra的4个连续字节进行符号扩展/零扩展到32bit，得到整数向量va
    // va[0]是最低字节的结果，va[3]是最高字节的结果，以此类推
    va = extractAndExtendPacked8bit(Ra, .afmt);
    // 根据.bfmt，将SrcB的4个连续字节进行符号扩展/零扩展到32bit，得到整数向量vb
    // vb[0]是最低字节的结果，vb[3]是最高字节的结果，以此类推
    vb = extractAndExtendPacked8bit(SrcB, .bfmt);
    // 计算va和vb两个四维向量的内积
    for (i = 0; i < 4; i++) {
        d += va[i] * vb[i];
    }
    // 4294967296 = 2^32 = 0x100000000
    pu = ceil(d / 4294967296) > 0 ? true : false;
    Rd = mod(d, 4294967296);
```

  __Examples
```asm
IDP.4A.U8.S8 R0, R1,         R2, 0x0;
IDP.4A.S8.S8 R0, R1, 0xAABBCCDD,  R3;
```

__DefOpcode IDP4A_RRR : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP4A_RRI : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RRI;
    field<32, 32> SImm32 vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP4A_RIR : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP4A_RRC : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, vc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP4A_RCR : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP4A_RRU : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RRU;
    field<32,  6> UReg urc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, urc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, urc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IDP4A_RUR : [IDP4A]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, urb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, urb, rc, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOptype IMUL : [IALU]
  __Encoding
    field<0,   8> Optype optype == IMUL;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;
    field<75,  1> LOHI lohi = LO;
    field<77,  1> IType itype = S32;

  __Syntax
```asm
IMUL.lohi.itype Rd, Ra, {-}SrcB      $sched $req ;

.lohi = {.LO*, .HI}
.itype = {.S32*, .U32}
```

  __Description
进行32bit整数乘法运算，即Rd = Ra * SrcB。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB可以是GPR、UR、Imm32或cmem。且可以添加一个负号(-)前缀，表示取相反数作为操作数。

  __ModifierInfo
.lohi可取值.LO（默认，可省略）或.HI，分别表示取Ra*SrcB乘积的低32bit或高32bit输出。

.itype可取值.S32（默认，可省略）或.U32，分别表示将Ra、SrcB视为有符号数或无符号数。

  __Semantics
```asm
IMUL.lohi.itype Rd, Ra, SrcB:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = a * b;
    if (.lohi == .LO)
        Rd = t[31:0];
    else
        Rd = t[63:32];
```

  __Examples
```asm
IMUL        R0, R1,       R2;
IMUL.HI.U32 R0, R1, 0x114514;
```

__DefOpcode IMUL_RR : [IMUL]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
    field<74,  1> SignModi rb.neg = False;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<rd>;
    Order<pg, rd, ra, rb>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IMUL_RU : [IMUL]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
    field<97,  1> SignModi urb.neg = False;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<rd>;
    Order<pg, rd, ra, urb>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IMUL_RI : [IMUL]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode IMUL_RC : [IMUL]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
    field<97,  1> SignModi vb.neg = False;
  __OperandInfo
    InList<pg, ra, vb>;
    OutList<rd>;
    Order<pg, rd, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype LEA : [IALU]
  __Encoding
    field<0,  8> Optype optype == LEA;
    field<16,  8> Reg rd;

    field<24,  8> Reg ra;
    field<72,  1> SignModi ra.neg = False;

    field<75,  1> LOHI lohi = LO;
    field<76,  1> IExt ext = NoX;
    field<80,  1> LEASX32 sx32 = NoSX32;
    field<82,  5> UImm5 shiftamt;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<106, 3> Pred pu = PT;

  __Syntax
```asm
LEA{.LO}      Rd{, pu}, {-}Ra, SrcB,     UImm5Sca               $sched $req ; // 32bit模式
LEA.HI.X      Rd{, pu}, {-}Ra, SrcB, Rc, UImm5Sca{, {!}pp}      $sched $req ; // 扩展位宽模式
LEA.HI.X.SX32 Rd{, pu}, {-}Ra, SrcB,     UImm5Sca{, {!}pp}      $sched $req ; // 符号扩展模式
```

  __Description
对整数进行2的幂缩放后，与基址相加。

根据修饰符的不同，分为3种模式：
- 32bit模式：  Rd,pu = (Ra << UImm5Sca) & 0xFFFFFFFF + SrcB;
- 扩展位宽模式：Rd,pu = (({URc,Ra} << UImm5Sca)>>32) & 0xFFFFFFFF + SrcB + pp;
- 符号扩展模式：Rd,pu = ((INT64(Ra) << UImm5Sca)>>32) & 0xFFFFFFFF + SrcB + pp;

每种模式的具体语义请参考Semantics部分。

  __OperandInfo
    AsmFormat<ra.neg> = CvtINegX(ra.neg, ext);

操作数Rd、Ra和Rc必须来源于GPR。

其中Rc操作数只在扩展位宽模式下使用。

32bit模式下，Ra可以选择添加一个负号(-)前缀，表示取相反数作为操作数。

扩展位宽模式下，Ra可以选择添加一个按位取反(~)前缀，表示对Ra和Rc组成的64bit输入{Rc, Ra}按位取反作为输入。

符号扩展模式下，Ra可以选择添加一个按位取反(~)前缀，表示Ra按位取反作为输入。

操作数SrcB的合法来源包括GPR、UR、Imm32和cmem。

UImm5Sca是一个5bit的无符号立即数（0~31），以2的幂表示缩放（scaling）的倍数，具体参考Semantics部分。

操作数pu和pp，分别表示输出进位和输入进位：

| pu | pp |
|:--:|:--:|
| PR | PR |

操作数pp可以选择添加一个逻辑非(!)前缀，表示取反作为操作数。

pu的默认值是PT，pp的默认值是!PT，二者取默认值时均可省略。

  __ModifierInfo
启用.LO修饰符时，表示取Ra缩放后的结果低32bit与SrcB相加，这是指令的默认模式，.LO也可以省略。

启用.HI.X修饰符时，表示进行扩展位宽的计算，此时以{Rc, Ra}作为64bit整数（Rc在高位，Ra在低位），取缩放结果的高32bit与SrcB和输入进位pp相加，结果写入Rd，并输出进位pu。

同时启用.HI.X和.SX32修饰符时，表示直接将有符号整数Ra符号扩展到64bit，再进行计算。

  __Semantics
```asm
LEA.LO Rd, pu, Ra, SrcB, UImm5Sca:
    // 左移UImm5Sca位，等价于放大2^UImm5Sca倍
    t = Ra << UImm5Sca;
    addr = t & 0xFFFFFFFF + SrcB;
    // 4294967296 = 2^32 = 0x100000000
    Rd = mod(addr, 4294967296);
    pu = addr > 4294967296 ? true : false;

LEA.HI.X Rd, pu, Ra, SrcB, Rc, UImm5Sca, pp:
    UINT64 t;
    t[63:32] = Rc[31:0];
    t[31:0] = Ra[31:0];
    // 先左移UImm5Sca位，再取高32位
    t = t >> (32 - UImm5Sca);
    addrHi = t & 0xFFFFFFFF + SrcB + pp;
    // 4294967296 = 2^32 = 0x100000000
    Rd = mod(addrHi, 4294967296);
    pu = addrHi > 4294967296 ? true : false;    

LEA.HI.X.SX32 Rd, pu, Ra, SrcB, UImm5Sca, pp:
    // 将Ra符号扩展到64bit
    INT64 t = signExtendTo64bit(Ra);
    // 先左移UImm5Sca位，再取高32位
    t = t >> (32 - UImm5Sca);
    addrHi = t & 0xFFFFFFFF + SrcB + pp;
    // 4294967296 = 2^32 = 0x100000000
    Rd = mod(addrHi, 4294967296);
    pu = addrHi > 4294967296 ? true : false;
```

  __Examples
```asm
LEA R0, R1, 0x10, R3; // R0 = (R1 << 16) + R3

LEA      R0, P0, R2, c[0x0][0x160], R7, RZ     ;
LEA.HI.X R1,     R2, c[0x0][0x160], R7, RZ, P0 ; // 联合完成R[0:1] = {R7,R2} << c[0x0][0x160]

LEA           R0, P0, -R2, R3, R4     ;
LEA.HI.X.SX32 R1,     ~R2, R3, R5, P0 ; // 联合完成R[0:1]=-R2<<R3 + R[4:5]
```

__DefOpcode LEA_RRR : [LEA]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<97,  1> SignModi rb.neg=False;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, rb, rc, shiftamt, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<rb.neg> = CvtINegX(rb.neg, ext);

__DefOpcode LEA_RIR : [LEA]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, shiftamt, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode LEA_RCR : [LEA]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<97,  1> SignModi vb.neg=False;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, vb, rc, shiftamt, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<vb.neg> = CvtINegX(vb.neg, ext);

__DefOpcode LEA_RUR : [LEA]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<97,  1> SignModi urb.neg=False;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, urb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, rd, pu, ra, urb, rc, shiftamt, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;
    AsmFormat<urb.neg> = CvtINegX(urb.neg, ext);

__DefOptype IABS : [IALU]
  __Encoding
    field<0,  8> Optype optype == IABS;
    field<16,  8> Reg rd;

  __Syntax
```asm
IABS Rd, {-}SrcB      $sched $req ;
```

  __Description
对32bit有符号整数取绝对值，即Rd = |SrcB|。

  __OperandInfo
输出操作数Rd来源必须是GPR。

输入操作数SrcB的合法来源可以是GPR、UR、SImm32或cmem，且允许添加一个负号（-）前缀，表示对来源取相反数作为操作数。

  __Semantics
```asm
IABS Rd, SrcB:
    Rd = |SrcB|;
```

  __Examples
```asm
IABS R0,   R1;
IABS R0, -0x1;  // 等价于IABS R0, 0xFFFFFFFF，结果R0 = 0x1
```

__DefOpcode IABS_R : [IABS]
  __Encoding
    field<8,   4> SType stype == R;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<rb> = 32;

__DefOpcode IABS_U : [IABS]
  __Encoding
    field<8,   4> SType stype == U;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<urb> = 32;

__DefOpcode IABS_I : [IABS]
  __Encoding
    field<8,   4> SType stype == I;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOpcode IABS_C : [IABS]
  __Encoding
    field<8,   4> SType stype == C;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOptype IMNMX : [IALU]
  __Encoding
    field<0,   8> Optype optype == IMNMX;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;
    field<77,  1> IType itype = S32;
    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not=False;

  __Syntax
```asm
IMNMX.itype Rd, {-}Ra, {-}SrcB, {!}pp      $sched $req ;

.itype = {.S32*, .U32}
```

  __Description
选取输入整数的最大/最小值输出：
- pp = true ，输出最小值
- pp = false，输出最大值

  __OperandInfo
Rd和Ra必须来源于GPR。

SrcB可以来源于GPR、UR、Imm32或cmem。

Ra和SrcB可以添加一个负号（-）前缀，表示取来源的相反数作为操作数。

pp必须来源于PR，且可以添加一个逻辑非（!）前缀，表示取反作为操作数。

  __ModifierInfo
.itype可取值.S32（默认，可省略）或.U32，分别表示将Ra、SrcB视为有符号数或无符号数。

  __Semantics
```asm
IMNMX.itype Rd, Ra, SrcB, pp:
    Rd = pp ? min(Ra, SrcB) : max(Ra, SrcB);
```

  __Examples
```asm
IMNMX R0, R1,  R2, !PT;
IMNMX R0, R1, 0x0,  P0;
```

__DefOpcode IMNMX_RR : [IMNMX]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode IMNMX_RU : [IMNMX]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode IMNMX_RI : [IMNMX]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode IMNMX_RC : [IMNMX]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOptype P2R : [IALU]
  __Encoding
    field<0,  8> Optype optype == P2R;
    field<16, 8> Reg rd;
    field<24, 8> Reg ra;
    field<79,  2> BSel bsel = B0;

  __Syntax
```asm          
P2R{.bsel} Rd, PR, Ra, SbMsk      $sched $req ;

.bsel = {.B0*, .B1, .B2, .B3}
```

  __Description
根据SbMsk的低8bit，从寄存器Ra和谓词寄存器P0~P7中选取一部分或全部，复制到结果寄存器中的指定位置。

  __OperandInfo
Rd和Ra均来源于GPR。

汇编助记符PR代表所有谓词寄存器P0~P7构成的集合，在指令书写/显示中不可变，可理解为汇编显示规则的一部分，而非指令操作数。

SbMsk的合法来源包括GPR、Imm32、cmem和UR。

  __ModifierInfo
.bsel的可取值包括.B0（默认值，可省略）、.B1、.B2和.B3，分别表示将结果复制到Rd的32bit中的哪些位，具体含义请参考Semantics部分。

  __Semantics
```asm
P2R.bsel Rd, PR, Ra, SbMsk:
    // 将predicate寄存器P0~P7的值打包成一个8bit数pr
    // pr的LSB是P0，MSB是P7
    pr = UINT8(0);
    pr = packPred2Byte(P0,P1,P2,P3,P4,P5,P6,P7);
    // 根据.bsel和SbMsk的低8bit，将pr和Ra中特定bit复制给Rd:
    // 如果SbMsk的第i位是1，则复制pr的第i位，否则复制Ra的相应位（i=0~7）
    b_select = SbMsk[0:7];
    switch (.bsel) {
        case .B0: 
            Rd[0:7] = (b_select & pr) | ((~b_select) & Ra[0:7]); 
            break;
        case .B1: 
            Rd[8:15] = (b_select & pr) | ((~b_select) & Ra[8:15]);
            break;
        case .B2: 
            Rd[16:23] = (b_select & pr) | ((~b_select) & Ra[16:23]);
            break;
        case .B3: 
            Rd[24:31] = (b_select & pr) | ((~b_select) & Ra[24:31]);
            break;
    }
```

  __Examples
```asm
P2R.B1 R7, PR, R0, 0xFF;
```

__DefOpcode P2R_RR : [P2R]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, PR, rb>;
    OutList<rd>;
    Order<pg, rd, PR, ra, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode P2R_RU : [P2R]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, ra, PR, urb>;
    OutList<rd>;
    Order<pg, rd, PR, ra, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode P2R_RI : [P2R]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, PR, vb>;
    OutList<rd>;
    Order<pg, rd, PR, ra, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode P2R_RC : [P2R]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, PR, vb>;
    OutList<rd>;
    Order<pg, rd, PR, ra, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOptype R2P : [IALU]
  __Encoding
    field<0,  8> Optype optype == R2P;
    field<24, 8> Reg ra;
    field<79, 2> BSel ra.bsel = B0;

  __Syntax
```asm          
R2P PR, Ra{.bsel}, SbMsk      $sched $req ;

.bsel = {.B0*, .B1, .B2, .B3}
```

  __Description
根据SbMsk的低8bit，从寄存器Ra中选取一部分，复制到谓词寄存器P0~P7中。

  __OperandInfo
汇编助记符PR代表所有谓词寄存器P0~P7构成的集合，在指令书写/显示中不可变，可理解为汇编显示规则的一部分，而非指令操作数。

Ra来源于GPR，可以带有一个后缀修饰符.bsel。

.bsel的可取值包括.B0（默认值，可省略）、.B1、.B2和.B3，分别表示将Ra的32bit中选取哪些比特，具体含义请参考Semantics部分。

SbMsk的合法来源包括GPR、Imm32、cmem和UR。

  __Semantics
```asm
R2P PR, Ra.bsel, SbMsk:
    // 将predicate寄存器P0~P7的值打包成一个8bit数pr
    // pr的LSB是P0，MSB是P7
    pr = UINT8(0);
    pr = packPred2Byte(P0,P1,P2,P3,P4,P5,P6,P7);
    // 根据.bsel和SbMsk的低8bit，将Ra中特定bit复制给pr:
    b_select = SbMsk[0:7];
    switch (.bsel) {
        case .B0: 
            pr = b_select & Ra[0:7]; 
            break;
        case .B1: 
            pr = b_select & Ra[8:15];
            break;
        case .B2: 
            pr = b_select & Ra[16:23];
            break;
        case .B3: 
            pr = b_select & Ra[24:31];
            break;
    }
    // 将pr的8bit分别复制给P0~P7
    // pr的LSB复制给P0，MSB复制给P7
    P0,P1,P2,P3,P4,P5,P6,P7 = unpackByte2Bits(pr);
```

  __Examples
```asm
R2P PR, R7.B1, 0xFF;
```

__DefOpcode R2P_RR : [R2P]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb>;
    OutList<PR>;
    Order<pg, PR, ra, rb>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode R2P_RU : [R2P]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<PR>;
    Order<pg, PR, ra, urb>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode R2P_RI : [R2P]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;

  __OperandInfo
    InList<pg, ra, vb>;
    OutList<PR>;
    Order<pg, PR, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode R2P_RC : [R2P]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;

  __OperandInfo
    InList<pg, ra, vb>;
    OutList<PR>;
    Order<pg, PR, ra, vb>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOptype ISETP : [IALU]
  __Encoding
    field<0,  8> Optype optype == ISETP;
    field<24, 8> Reg ra;

    field<76,  1> IExt ext = NoX;
    field<77,  1> IType itype = S32;
    field<79,  3> CompOp compop;
    field<82,  2> BoolOp boolop;

    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not=False;
    field<102, 3> Pred pq = PT;
    field<105, 1> PModi pq.not=False;
    field<106, 3> Pred pu;
    field<109, 3> Pred pv = PT;

  __Syntax
```asm          
ISETP.compop.boolop{.itype}   pu{, pv}, Ra, SrcB, {!}pp               $sched $req ;
ISETP.compop.boolop{.itype}.X pu{, pv}, Ra, SrcB, {!}pp{, {!}pq}      $sched $req ;

.compop = {.EQ, .NE, .LT, .LE, .GT, .GE}
.boolop = {.AND, .OR, .XOR}
.itype = {.S32*, .U32}
```

  __Description
对2个输入整数进行指定的算术比较，将比较结果（布尔值）与一个额外的输入谓词进行指定的布尔运算，得到输出（布尔值）。

  __OperandInfo
Ra只能来源于GPR。

SrcB可以是GPR、UR、Imm32或cmem。

输出操作数pu、pv，输入操作数pp、pq均为谓词，来源只能是PR。

输出操作数pv的默认值是PT（可以省略），表示舍弃pv的计算结果。

输入操作数pp和pq可以添加一个逻辑非(!)前缀，表示取反作为操作数。其中pq的默认值是!PT（可以省略）。

  __ModifierInfo
.compop决定对Ra、SrcB所作的算术比较，其可取值及其对应的比较操作为：

| .compop | 功能（C风格比较运算符表示） |
|:--:|:--:|
| .EQ | == |
| .NE | != |
| .LT | <  |
| .LE | <= |
| .GT | >  |
| .GE | >= |

.boolop决定了将Ra、SrcB的比较结果与输入布尔值（操作数pp）进行何种布尔运算：

| .boolop | 功能（C风格逻辑运算符表示） |
|:--:|:--:|
| .AND | && |
| .OR  | \|\| |
| .XOR | ^ |

.itype可取值.S32（默认，可省略）或.U32，分别表示将Ra、SrcB视为有符号数或无符号数。

.X用于对扩展位宽（大于32bit）的整数进行比较。

  __Semantics
```asm
// 32bit整数比较
ISETP.compop.boolop.itype pu, pv, Ra, SrcB, pp:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = a compop b ? true : false;
    pu = t boolop pp;
    pv = (!t) boolop pp;

// 扩展位宽的整数比较
ISETP.compop.boolop.itype.EX pu, pv, Ra, SrcB, pp, pq:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    if (a == b) 
        pu = pq boolop pp;
        pv = (!pq) boolop pp;
    else
        t = a compop b ? true : false;
        pu = t boolop pp;
        pv = (!t) boolop pp;
```

  __Examples
```asm
ISETP.LE.U32.AND P0, PT, R4,  R6, PT     ;
ISETP.GT.OR.X    P0,     R5, 0x0, PT, P0 ;
```

__DefOpcode ISETP_RR : [ISETP]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, pp, pq>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, rb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;

__DefOpcode ISETP_RU : [ISETP]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb, pp, pq>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, urb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOpcode ISETP_RI : [ISETP]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb, pp, pq>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, vb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOpcode ISETP_RC : [ISETP]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb, pp, pq>;
    OutList<pu, pv>;
    Order<pg, pu, pv, ra, vb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;

__DefOptype ISET : [IALU]
  __Encoding
    field<0,  8> Optype optype == ISET;
    field<16,  8> Reg rd;
    field<24, 8> Reg ra;

    field<76,  1> IExt ext = NoX;
    field<77,  1> IType itype = S32;
    field<79,  3> CompOp compop;
    field<82,  2> BoolOp boolop = AND;
    field<84,  1> BMBF bmbf = BM;

    field<98, 3> Pred pp = PT;
    field<101, 1> PModi pp.not=True;
    field<102, 3> Pred pq = PT;
    field<105, 1> PModi pq.not=True;

  __Syntax
```asm          
ISET.compop{.boolop}{.itype}{.bmbf}    Rd, Ra, SrcB{, {!}pp}               $sched $req ;
ISET.compop{.boolop}{.itype}{.bmbf}.X  Rd, Ra, SrcB{, {!}pp}{, {!}pq}      $sched $req ;

.compop = {.EQ, .NE, .LT, .LE, .GT, .GE}
.boolop = {.AND*, .OR, .XOR}
.itype = {.S32*, .U32}
.bmbf = {.BM*, .BF}
```

  __Description
对2个输入整数进行指定的算术比较，将比较结果（布尔值）与一个额外的输入谓词进行指定的布尔运算，得到输出。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB可以是GPR、UR、Imm32或cmem。

输入操作数pp和pq只能来源于PR，可以添加一个逻辑非(!)前缀，表示取反作为操作数。
pp与pq的默认值都是!PT，此时可以省略。

  __ModifierInfo
.compop决定对Ra、SrcB所作的算术比较，其可取值及其对应的比较操作为：

| .compop | 功能（C风格比较运算符表示） |
|:--:|:--:|
| .EQ | == |
| .NE | != |
| .LT | <  |
| .LE | <= |
| .GT | >  |
| .GE | >= |

.boolop决定了将Ra、SrcB的比较结果与输入布尔值（操作数pp）进行何种布尔运算：

| .boolop | 功能（C风格逻辑运算符表示） |
|:--:|:--:|
| .AND（默认） | && |
| .OR  | \|\| |
| .XOR | ^ |

.boolop的默认值是.AND，此时可以省略。

.itype可取值.S32（默认，可省略）或.U32，分别表示将Ra、SrcB视为有符号数或无符号数。

.bmbf可取值为.BM（默认，可省略）或.BF，用于决定最终布尔运算的结果（布尔值）如何转换为输出操作数Rd的32bit寄存器值：

| 比较结果 | .BM | .BF |
|:-------:|:----|:----|
| true  | 0xFFFFFFFF  | 0x3F800000 |
| false | 0x00000000  | 0x00000000 |

.X用于对扩展位宽（大于32bit）的整数进行比较。

  __Semantics
```asm
// 32bit整数比较
ISET.compop.boolop.itype.bmbf Rd, Ra, SrcB, pp:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = (a compop b) ? true : false;
    if (.bmbf == .BM)
        Rd = (t boolop pp) ? 0xFFFFFFFF : 0x00000000;
    else
        Rd = (t boolop pp) ? 0x3F800000 : 0x00000000;

// 扩展位宽的整数比较
ISET.compop.boolop.itype.bmbf.EX Rd, Ra, SrcB, pp, pq:
    if (.itype == .S32)
        a = INT32(Ra);
        b = INT32(SrcB);
    else
        a = UINT32(Ra);
        b = UINT32(SrcB);
    t = (a == b) ? pq : (a compop b);
    if (.bmbf == .BM)
        Rd = (t boolop pp) ? 0xFFFFFFFF : 0x00000000;
    else
        Rd = (t boolop pp) ? 0x3F800000 : 0x00000000;
```

  __Examples
```asm
ISET.LE.U32     R0, R4, R6         ;
ISET.GT.OR.BF.X R0, R5, 0x0, PT, P0;
```

__DefOpcode ISET_RR : [ISET]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, pp, pq>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode ISET_RU : [ISET]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb, pp, pq>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode ISET_RI : [ISET]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb, pp, pq>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode ISET_RC : [ISET]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb, pp, pq>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp, pq>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype SEL : [IALU]
  __Encoding
    field<0,  8> Optype optype == SEL;
    field<16,  8> Reg rd;
    field<24, 8> Reg ra;
    field<98, 3> Pred pp;
    field<101, 1> PModi pp.not=False;

  __Syntax
```asm          
SEL Rd, Ra, SrcB, {!}pp      $sched $req ;
```

  __Description
根据谓词pp的值，选择将Ra或SrcB的值赋予给Rd。

可以认为语义上等价于C语言的三元表达式。

  __OperandInfo
Rd和Ra来源于GPR。

SrcB的合法来源包括GPR、Imm32、cmem和UR。

pp来源于PR，可以带有一个逻辑非修饰符（!），表示对来源取反作为操作数。

  __Semantics
```asm
SEL Rd, Ra, SrcB, pp:
    Rd = pp ? Ra : SrcB;
```

  __Examples
```asm
SEL R0, R1, R2, !P0;
```

__DefOpcode SEL_RR : [SEL]
  __Encoding
    field<8,   4> SType stype == RR;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, rb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SEL_RU : [SEL]
  __Encoding
    field<8,   4> SType stype == RU;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, urb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SEL_RI : [SEL]
  __Encoding
    field<8,   4> SType stype == RI;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SEL_RC : [SEL]
  __Encoding
    field<8,   4> SType stype == RC;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb, pp>;
    OutList<rd>;
    Order<pg, rd, ra, vb, pp>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rd> = 32;

__DefOptype LOP3 : [IALU]
  __Encoding
    field<0,    8> Optype optype == LOP3;
    field<16,   8> Reg rd;
    field<24,   8> Reg ra;
    field<79,   2> EXBool exbool = POR;
    field<82,   8> UImm8  lut;
    field<98,   3> Pred pp;
    field<101,  1> PModi pp.not=False;
    field<106,  3> Pred pu = PT;

  __Syntax
```asm          
LOP3.exbool {pu, }Rd, Ra, SrcB, Rc, UImm8Lut, {!}pp      $sched $req ;

.exbool = {.PAND, .POR}
```

  __Description
对3个输入操作数Ra、SrcB和Rc的每个bit，按照真值表UImm8Lut指定的输入-输出映射关系，进行逻辑运算，结果写入Rd的对应bit。

允许将计算结果Rd与一个输入谓词pp进行指定的逻辑运算，结果写入谓词pu。

  __OperandInfo
Rd、Ra和Rc均来源于GPR。

SrcB的合法来源包括GPR、Imm32、cmem和UR。

UImm8Lut必须是一个UImm8立即数，用于描述输入（Ra、SrcB、Rc）-输出（Rd）的映射关系，具体解释请参考Semantics部分。

谓词操作数pu和pp都来源于PR，其中pu的默认值是PT（可省略），pp允许添加一个逻辑非（!）前缀，表示将来源取反后作为操作数。

  __ModifierInfo
.exbool修饰符的可取值是.PAND或.POR，分别表示将Rd的计算结果与输入操作数pp进行逻辑与/逻辑或运算，结果写入输出操作数pu，具体规则请参考Semantics部分。

  __Semantics
```asm
LOP3.exbool pu, Rd, Ra, SrcB, Rc, UImm8Lut, pp:
    // 根据真值表UImm8Lut获得输入-输出之间的映射关系
    F = getFunctionFromTable(UImm8Lut);
    Rd = F(Ra, SrcB, Rc);
    // 执行额外的逻辑运算
    if (.exbool == .PAND) {
        pu = (Rd != 0) & pp;
    } else {
        pu = (Rd != 0) | pp;
    }
```

Ra、SrcB和Rc的每个bit，都有2种可能的取值（0或1），因此由它们的某一bit共同组成的3bit输入总共有2^3 = 8种可能，可以用一个8种情况的真值表来描述所有情况输入对应的输出。

任意一个这样的真值表都可以用一个8bit的无符号整数UImm8Lut来代表，因此可以用它来定义输入-输出之间的逻辑映射关系d = F(a, b, c)。

如果已知F，可以按照如下方式计算对应的UImm8Lut：
```asm
UImm8Lut = F(0xF0, 0xCC, 0xAA);
```
例如：
```asm
if F(a, b, c) = (a & b & c);
UImm8Lut = 0xF0 & 0xCC & 0xAA = 0x80

if F(a, b, c) = (a | b | c);
UImm8Lut = 0xF0 | 0xCC | 0xAA = 0xFE

if F(a, b, c) = (a & b & ~c);
UImm8Lut = 0xF0 & 0xCC & (~0xAA) = 0x40

if F(a, b, c) = ((a & b | c) ^ a);
UImm8Lut = (0xF0 & 0xCC | 0xAA) ^ 0xF0 = 0x1A
```

反过来，如果已知UImm8Lut，可以按照下面的方式，根据输入逐bit计算输出：
```asm
d[i] = UImm8Lut[(a[i] << 2) | (b[i] << 1) | c[i]];
```

__Examples
```asm
LOP3.POR      R7, R7, RZ, R0, 0x1A, !PT ;
LOP3.PAND P1, R7, R1, RZ, R0, 0x1A,  P0 ;
```

__DefOpcode LOP3_RRR : [LOP3]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, rb, rc, lut, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode LOP3_RIR : [LOP3]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, vb, rc, lut, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode LOP3_RCR : [LOP3]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, vb, rc, lut, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode LOP3_RUR : [LOP3]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, urb, rc, pp>;
    OutList<rd, pu>;
    Order<pg, pu, rd, ra, urb, rc, lut, pp>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;

__DefOptype PLOP3 : [IALU]
  __Encoding
    field<0,    8> Optype optype == PLOP3;
    field<24,   3> Pred pa;
    field<27,   1> PModi pa.not = False;
    field<32,   3> Pred pb;
    field<35,   1> PModi pb.not = False;
    field<82,   8> UImm8  lut;
    field<106,  3> Pred pu;

  __Syntax
```asm          
PLOP3 pu, {!}pa, {!}pb, {!}pc, UImm8Lut      $sched $req ;
```

  __Description
对3个输入谓词pa、pb和pc（可视为单bit操作数），按照真值表UImm8Lut指定的输入-输出映射关系，进行逻辑运算，结果写入输出谓词pu。

  __OperandInfo
所有操作数均为谓词，必须来源于PR。pa、pb和pc允许添加一个逻辑非（!）前缀，表示将来源取反后作为操作数。

UImm8Lut必须是一个UImm8立即数，用于描述输入-输出的映射关系，具体解释请参考Semantics部分。

  __Semantics
```asm
PLOP3 pu, pa, pb, pc, UImm8Lut:
    // 根据真值表UImm8Lut获得输入-输出之间的映射关系
    F = getFunctionFromTable(UImm8Lut);
    pu = F(pa, pb, pc);
```

pa, pb, pc每个操作数都有2种可能的取值（false或true），因此由它们共同组成的3bit输入总共有2^3 = 8种可能，可以用一个8种情况的真值表来描述所有情况输入对应的输出。

任意一个这样的真值表都可以用一个8bit的无符号整数UImm8Lut来代表（为0的bit代表输出false，为1的bit代表输出true），因此可以用它来定义输入-输出之间的映射关系d = F(a, b, c)。

如果已知F，可以按照如下方式计算对应的UImm8Lut：
```asm
UImm8Lut = F(0xF0, 0xCC, 0xAA);
```
例如：
```asm
if F(a, b, c) = (a & b & c);
UImm8Lut = 0xF0 & 0xCC & 0xAA = 0x80

if F(a, b, c) = (a | b | c);
UImm8Lut = 0xF0 | 0xCC | 0xAA = 0xFE

if F(a, b, c) = (a & b & ~c);
UImm8Lut = 0xF0 & 0xCC & (~0xAA) = 0x40

if F(a, b, c) = ((a & b | c) ^ a);
UImm8Lut = (0xF0 & 0xCC | 0xAA) ^ 0xF0 = 0x1A
```

反过来，如果已知UImm8Lut，可以按照下面的方式，根据输入bit计算输出bit：
```asm
out = UImm8Lut[(a << 2) | (b << 1) | c];
```

  __Examples
```asm
PLOP3 P0, P1, !P2, P3, 0x1A;
```

__DefOpcode PLOP3_X : [PLOP3]
  __Encoding
    field<8,   4> SType stype == X;
    field<64,   3> Pred pc;
    field<67,   1> PModi pc.not = False;
  __OperandInfo
    InList<pg, pa, pb, pc>;
    OutList<pu>;
    Order<pg, pu, pa, pb, pc, lut>;

__DefOpcode PLOP3_U : [PLOP3]
  __Encoding
    field<8,   4> SType stype == U;
    field<64,   3> UPred upc;
    field<67,   1> PModi upc.not = False;
  __OperandInfo
    InList<pg, pa, pb, upc>;
    OutList<pu>;
    Order<pg, pu, pa, pb, upc, lut>;

__DefOptype SHF : [IALU]
  __Encoding
    field<0,   8> Optype optype == SHF;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;

    field<75,  1> LOHI lohi = LO;
    field<77,  2> SHFDType itype = S32;
    field<80,  1> CWMode cwmod = C;
    field<81,  1> SHFDir direction;

  __Syntax
```asm          
SHF.direction{.lohi}{.cwmod}{.itype} Rd, Ra, SrcB, SrcC      $sched $req ;

.direction = {.L, .R}
.lohi = {.LO*, .HI}
.cwmod = {.CLAMP*, .WRAP}
.itype = {.S32*, .U32, .S64, .U64}
```

  __Description
对2个输入32bit数Ra和SrcC进行拼接（低32bit是Ra，高32bit是SrcC），根据.direction指定的方向和SrcB指定的位数移位后，输出结果的低32bit或高32bit。

指令名SHF是funnel shift的含义。

  __OperandInfo
Rd和Ra必须来源于GPR。

SrcB和SrcC的所有合法来源组合如下：

| SrcB | SrcC |
| :--: | :--: |
| GPR | GPR |
| GPR |Imm32|
|UImm32| GPR |
| GPR |cmem |
|cmem | GPR |
| GPR | UR  |
| UR  | GPR |

其中SrcB将被视为无符号32bit整数，用于决定移位的位数。

  __ModifierInfo
.direction可取.L或.R，分别表示左移或右移。

.lohi可取.LO（默认值，可省略）或.HI，分别表示输出结果的低32bit或高32bit。

.cwmod可取.CLAMP（默认值，可省略）或.WRAP，分别表示移位的位数超出有效位数的上限N时，采取截断还是循环的处理方式来获得实际移位数:
- .cwmod = .CLAMP：若SrcB > N，则将URa视为N位的整数
- .cwmod = .WRAP ：若SrcB > N，则将URa视为mod(SrcB, N)位的整数

因此，在.CLAMP模式下，移位的位数在0~N之间，而在.WRAP模式下，移位的位数在0~N-1之间。

.itype可取值及其含义如下：

| .itype | 描述 |
| :--: | :--- |
| .S32（默认值，可省略） | 右移时符号扩展，移位的有效位数上限是32 |
| .U32 | 右移时零扩展，移位的有效位数上限是32 |
| .S64 | 右移时符号扩展，移位的有效位数上限是64 |
| .U64 | 右移时零扩展，移位的有效位数上限是64 |

也就是说，.itype是无符号类型时，表示进行逻辑移位，否则进行的都是算术移位。

  __Semantics
```asm
SHF.direction.lohi.cwmod.itype Rd, Ra, SrcB, SrcC:
    // 将Ra与SrcC拼接成64bit数
    UINT64 t;
    t[31:0] = Ra;
    t[63:32] = SrcC;
    // 根据.itype确定有效移位位数的上限
    n_ub = (.itype == .S64 || .itype == .U64) ? 64 : 32;
    // 根据.cwmod和SrcB确定有效移位位数
    b = UINT32(SrcB);
    n = (.cwmod == .CLAMP) ? min(n_ub, ) : min(b, n_ub) : mod(b, n_ub);
    // 根据.direction的方向进行移位
    if (.direction == .L) {
        // 左移
        t = t << n;
    } else {
        // 右移n位，并根据.itype决定对高位做符号扩展还是零扩展
        t = signOrZeroExtendShiftRight(t, n, .itype);
    }
    // 根据.lohi，输出低32bit或高32bit
    if (.lohi == .LO) {
        Rd = t & 0xFFFFFFFF;
    } else {
        Rd = (t >> 32) & 0xFFFFFFFF;
    }
```

  __Examples
```asm
SHF.L.HI.S32 R7, R7, 0x24, R0; // 由于0x24大于移位数的上限32，在.CLAMP模式下只做32位左移
```

__DefOpcode SHF_RRR : [SHF]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SHF_RRI : [SHF]
  __Encoding
    field<8,   4> SType stype == RRI;
    field<32, 32> SImm32 vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SHF_RIR : [SHF]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SHF_RRC : [SHF]
  __Encoding
    field<8,   4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SHF_RCR : [SHF]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SHF_RRU : [SHF]
  __Encoding
    field<8,   4> SType stype == RRU;
    field<32,  6> UReg urc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, urc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, urc>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode SHF_RUR : [SHF]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, urb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, urb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOptype MOV : [IALU]
  __Encoding
    field<0,  8> Optype optype == MOV;
    field<16,  8> Reg rd;

  __Syntax
```asm          
MOV{.32} Rd, SrcA      $sched $req ;
MOV.64   Rd, Ra        $sched $req ;
```

  __Description
将源操作数的值精确复制给目的寄存器Rd。

  __OperandInfo
Rd必须来源于GPR，对于MOV.64指令，输入Ra和输出Rd都必须来源于64bit寄存器。

关于如何表示大于32bit位宽的寄存器操作数，请参考[扩展位宽的寄存器操作数](操作数汇编显示规则.md#扩展位宽的寄存器操作数)。

源操作数SrcA的合法来源包括GPR、UR、Imm32和cmem。

  __ModifierInfo
MOV指令的修饰符可以是.32或.64，分别表示MOV操作的位宽是32bit还是64bit。

默认情况下MOV指令的操作位宽就是32bit，此时可以省略.32修饰符。

  __Semantics
```asm
MOV.32 Rd, SrcA:
    Rd[31:0] = SrcA[31:0];

MOV.64 Rd, Ra:
    Rd[63:0] = Ra[63:0];
```

  __Examples
```asm
MOV R0,       R1;   // MOV.32 R0, R1也可以，表示R0 = R1
MOV R0, 0x114514;   // R0 = 0x114514

MOV.64 R[0:1], R[2:3]; // R[0:1] = R[2:3]
```

__DefOpcode MOV_R : [MOV]
  __Encoding
    field<8,   4> SType stype == R;
    field<32,  8> Reg rb;
    field<80,  1> MOVW width = 32;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32 + (width=="64")*32;
    Bitwidth<rb> = 32 + (width=="64")*32;

__DefOpcode MOV_U : [MOV]
  __Encoding
    field<8,   4> SType stype == U;
    field<32,  6> UReg urb;
    field<80,  1> MOVW width = 32;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32 + (width=="64")*32;
    Bitwidth<urb> = 32 + (width=="64")*32;

__DefOpcode MOV_I : [MOV]
  __Encoding
    field<8,   4> SType stype == I;
    field<32, 32> SImm32 vb;
    field<80,  1> MOVW width = 32;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32 + (width=="64")*32;
    Bitwidth<vb> = 32;
  __Exception
    EncodingError<IllegalBitFieldValue, "MOV_I does not support .64 ."> = width=="64";

__DefOpcode MOV_C : [MOV]
  __Encoding
    field<8,   4> SType stype == C;
    field<32, 22> CMem vb;
    field<80,  1> MOVW width = 32;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32 + (width=="64")*32;
    Bitwidth<vb> = 32 + (width=="64")*32;

__DefOptype PRMT : [IALU]
  __Encoding
    field<0,   8> Optype optype == PRMT;
    field<16,  8> Reg rd;
    field<24,  8> Reg ra;
    field<76,  3> PRMTMode mode = IDX;

  __Syntax
```asm          
PRMT{.mode} Rd, Ra, SrcB, SrcC      $sched $req ;

.mode = {.IDX*, .F4E, .B4E, .RC8, .ECL, .ECR, .RC16}
```

  __Description
从32bit输入操作数Ra与SrcB中选取4字节输出到Rd。

  __OperandInfo
Ra和Rd必须来源于GPR。

SrcB和SrcC的所有合法来源组合如下：
| SrcB | SrcC |
|:--:|:--:|
| GPR | GPR |
| GPR | Imm32 |
| Imm32 | GPR |
| GPR |cmem |
|cmem | GPR |
| GPR | UR  |
| UR  | GPR |

  __ModifierInfo
.mode可取值包括.IDX（默认值，可省略）、.F4E、.B4E、.RC8、.ECL、.ECR和.RC16。

将两个32bit输入操作数Ra与SrcB所包含的8个字节编号为0~7：
```asm
{Src, Ra} = {{b7, b6, b5, b4}, {b3, b2, b1, b0}}
```

其中b0~b3来自Ra（b0是Ra的低8bit，依此类推），b4~b7来自SrcB（b4是SrcB的低8bit，依此类推）。

同理，将输出32bit操作数Rd所包含的4个字节按照从低位到高位的顺序编号为0~3：
```asm
Rd = {Rd.b3, Rd.b2, Rd.b1, Rd.b0}
```

其中Rd.b0表示Rd的低8bit，依此类推。

# .IDX模式

将SrcC[16:0]分为4个4bit区段，将每个区段分配给Rd的一个字节（SrcC[3:0]分配给Rd.b0，Src[7:4]分配给Rd.b1，依此类推）。

根据每个区段的低3bit，从b0~b7中选取一个字节b_selected。

如果区段的MSB是0，则直接将b_selected复制给Rd的对应字节；否则，将Rd的对应字节完全置为b_selected的符号位（即b_selected的MSB，b_selected[7]）。

# 其他模式

在.IDX之外的其他模式下，以SrcC的低2bit作为selector，即selector = SrcC[1:0]。

根据.mode和selector的组合，选取b0~b7复制给Rd的相应字节，具体规则如下：

## .F4E

| selector | Rd.b0 | Rd.b1 | Rd.b2 | Rd.b3 |
|:--:|:--:|:--:|:--:|:--:|
| 0x0 | b3 | b2 | b1 | b0 |
| 0x1 | b4 | b3 | b2 | b1 |
| 0x2 | b5 | b4 | b3 | b2 |
| 0x3 | b6 | b5 | b4 | b3 |

## .B4E

| selector | Rd.b0 | Rd.b1 | Rd.b2 | Rd.b3 |
|:--:|:--:|:--:|:--:|:--:|
| 0x0 | b5 | b6 | b7 | b0 |
| 0x1 | b6 | b7 | b0 | b1 |
| 0x2 | b7 | b0 | b1 | b2 |
| 0x3 | b0 | b1 | b2 | b3 |

## .RC8

| selector | Rd.b0 | Rd.b1 | Rd.b2 | Rd.b3 |
|:--:|:--:|:--:|:--:|:--:|
| 0x0 | b0 | b0 | b0 | b0 |
| 0x1 | b1 | b1 | b1 | b1 |
| 0x2 | b2 | b2 | b2 | b2 |
| 0x3 | b3 | b3 | b3 | b3 |

## .ECL

| selector | Rd.b0 | Rd.b1 | Rd.b2 | Rd.b3 |
|:--:|:--:|:--:|:--:|:--:|
| 0x0 | b3 | b2 | b1 | b0 |
| 0x1 | b3 | b2 | b1 | b1 |
| 0x2 | b3 | b2 | b2 | b2 |
| 0x3 | b3 | b3 | b3 | b3 |

## .ECR

| selector | Rd.b0 | Rd.b1 | Rd.b2 | Rd.b3 |
|:--:|:--:|:--:|:--:|:--:|
| 0x0 | b0 | b0 | b0 | b0 |
| 0x1 | b1 | b1 | b1 | b0 |
| 0x2 | b2 | b2 | b1 | b0 |
| 0x3 | b3 | b2 | b1 | b0 |

## .RC16

| selector | Rd.b0 | Rd.b1 | Rd.b2 | Rd.b3 |
|:--:|:--:|:--:|:--:|:--:|
| 0x0 | b1 | b0 | b1 | b0 |
| 0x1 | b3 | b2 | b3 | b2 |
| 0x2 | b1 | b0 | b1 | b0 |
| 0x3 | b3 | b2 | b3 | b2 |

  __Semantics
```asm
PRMT.mode Rd, Ra, SrcB, SrcC:
    UINT64 t = (SrcB << 32) | Ra;
    if (.mode == .IDX) {
        ctl[0] = (SrcC >>  0) & 0xF;
        ctl[1] = (SrcC >>  4) & 0xF;
        ctl[2] = (SrcC >>  8) & 0xF;
        ctl[3] = (SrcC >> 12) & 0xF;
    } else {
        ctl[0] = ctl[1] = ctl[2] = ctl[3] = (SrcC & 0x3);
    }
    // 根据.mode从t的8个字节中选择输出到Rd的部分
    Rd[7:0]   = ReadByte(.mode, ctl[0], t);
    Rd[15:8]  = ReadByte(.mode, ctl[1], t);
    Rd[23:16] = ReadByte(.mode, ctl[2], t);
    Rd[31:24] = ReadByte(.mode, ctl[3], t);
```

  __Examples
```asm
PRMT R0, R1, R2, 0xABCD;
```

__DefOpcode PRMT_RRR : [PRMT]
  __Encoding
    field<8,   4> SType stype == RRR;
    field<32,  8> Reg rb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, rb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode PRMT_RRI : [PRMT]
  __Encoding
    field<8,   4> SType stype == RRI;
    field<32, 32> SImm32 vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;

__DefOpcode PRMT_RIR : [PRMT]
  __Encoding
    field<8,   4> SType stype == RIR;
    field<32, 32> SImm32 vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode PRMT_RRC : [PRMT]
  __Encoding
    field<8,   4> SType stype == RRC;
    field<32, 22> CMem vc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, vc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, vc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<vc> = 32;

__DefOpcode PRMT_RCR : [PRMT]
  __Encoding
    field<8,   4> SType stype == RCR;
    field<32, 22> CMem vb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;

__DefOpcode PRMT_RRU : [PRMT]
  __Encoding
    field<8,   4> SType stype == RRU;
    field<32,  6> UReg urc;
    field<64,  8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, urc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, urc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<urc> = 32;

__DefOpcode PRMT_RUR : [PRMT]
  __Encoding
    field<8,   4> SType stype == RUR;
    field<32,  6> UReg urb;
    field<64,  8> Reg rc;
  __OperandInfo
    InList<pg, ra, urb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, urb, rc>;
    Bitwidth<rd> = 32;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;

__DefOptype I2I : [IALU]
  __Encoding
    field<0,  8> Optype optype == I2I;
    field<16,  8> Reg rd;
    field<76, 2> I2IDType dtype;

  __Syntax
```asm          
I2I.dtype Rd, SrcB      $sched $req ;

.dtype = {.S8, .U8, .S16, .U16}
```

  __Description
将32bit有符号整数SrcB饱和转换成更低位宽的整数，并输出给Rd。

饱和转换的规则是：
- 如果输入的SrcB大于输出类型可表达的最大值，则只输出最大值
- 如果输入的SrcB小于输出类型可表达的最小值，则只输出最小值

  __OperandInfo
Rd必须来源于GPR。

SrcB的来源可以是GPR、UR、SImm32或cmem。

  __ModifierInfo
.dtype可以是.S8、.U8、.S16或.U16，分别表示将SrcB转换成INT8、UINT8、INT16或UINT16类型输出。

  __Semantics
```asm
I2I.dtype Rd, SrcB:
    // 确定输出类型可表达的最大最小整数
    MININT = MIN(.dtype);
    MAXINT = MAX(.dtype);
    // 进行饱和转换
    if (SrcB < MININT) {
        Rd = MININT;
    } else if (SrcB > MAXINT) {
        Rd = MAXINT;
    } else {
        Rd = SrcB;
    }
```

  __Examples
```asm
I2I.S16 R0, R1;
I2I.U16 R0, 0x114514;   // 由于0x114514大于UINT16可表达的最大值，将饱和到R0 = 0xFFFF
```

__DefOpcode I2I_R : [I2I]
  __Encoding
    field<8,   4> SType stype == R;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, rb>;
    OutList<rd>;
    Order<pg, rd, rb>;
    Bitwidth<rd> = 32;
    Bitwidth<rb> = 32;

__DefOpcode I2I_U : [I2I]
  __Encoding
    field<8,   4> SType stype == U;
    field<32,  6> UReg urb;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, urb>;
    Bitwidth<rd> = 32;
    Bitwidth<urb> = 32;

__DefOpcode I2I_I : [I2I]
  __Encoding
    field<8,   4> SType stype == I;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOpcode I2I_C : [I2I]
  __Encoding
    field<8,   4> SType stype == C;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, vb>;
    OutList<rd>;
    Order<pg, rd, vb>;
    Bitwidth<rd> = 32;
    Bitwidth<vb> = 32;

__DefOptype I2IP : [IALU]
  __Encoding
    field<0,  8> Optype optype == I2IP;
    field<16,  8> Reg rd;

    field<24, 8> Reg ra;
    field<64, 8> Reg rc;

    field<75, 1> SATRelu satrelu==SAT;
    field<76, 3> I2IPDType dsttype;

  __Syntax
```asm          
I2IP.dsttype.satrelu Rd, Ra, SrcB, Rc $sched $req ;

.dsttype = {.S2, .U2, .S4, .U4, .S8, .U8, .S16, .U16}
satrelu = {.SAT*, .SATRELU}
```

  __Description
将2个32bit有符号整数按要求转换成低位宽的整数，打包（pack）后写入Rd：
- SrcB的转换结果被打包到Rd的低位
- Ra  的转换结果被打包到Rd的高位，并紧邻SrcB的转换结果
- Rd高位的剩余比特（如果还有的话）将由Rc的低位填充（填满为止）

具体语义请参考Semantics部分。

  __OperandInfo
Rd、Ra和Rc必须来源于GPR。

SrcB的来源可以是GPR、UR、SImm32或cmem。

  __ModifierInfo
.dsttype可以是.S2、.U2、.S4、.U4、.S8、.U8、.S16或.U16，表示转换的目的类型。

.satrelu可以是.SAT（默认值）或.SATRELU，表示转换结果采取的饱和处理方式：

| .satrelu | 处理方式 |
|:------|:--------|
| .SAT | 结果保留到目的类型（.dsttype）可表达的最大最小值之间 |
|.SATRELU | 结果保留到0~目的类型（.dsttype）可表达的最大值之间 |

具体的语义请参考Semantics部分。

  __Semantics
```asm
I2IP.dsttype.satrelu Rd, Ra, SrcB, Rc:
    // 首先对输入转换结果进行饱和操作
    // MAX(.dsttype)和MIN(.dsttype)是.dsttype类型可表示的最大最小值
    ta = Ra < MIN(.dsttype) ? MIN(.dsttype) : Ra;
    ta = Ra > MAX(.dsttype) ? MAX(.dsttype) : Ra;
    tb = SrcB < MIN(.dsttype) ? MIN(.dsttype) : SrcB;
    tb = SrcB > MAX(.dsttype) ? MAX(.dsttype) : SrcB;
    // 根据.satrelu决定是否要进行额外的Relu操作（负数被转换为0）
    if (.satrelu == .SATRELU) {
        ta = ta > 0 ? ta : 0;
        tb = tb > 0 ? tb : 0;
    }
    // 将转换后的结果打包写入Rd的低比特位（SrcB在低位，Ra在高位）
    msk = (1 << size) - 1;
    size = sizeInBitsOf(.dsttype);
    Rd = ((ta & msk) << size) | (tb & msk);
    // 如果Rd还有剩余未填满的bit，则使用Rc的低bit填充
    if (size < 16) {
        rest = 32 - size * 2;
        cmsk = (1 << rest) - 1;
        Rd = Rd | ((Rc & cmsk) << (2 * size))
    }
```

  __Examples
```asm
I2IP.U16.SAT R0, R1, R2, RZ;
I2IP.S4.SATRELU R0, R1, R2, RZ;
```

__DefOpcode I2IP_RRR : [I2IP]
  __Encoding
    field<8, 4> SType stype==RRR;
    field<32, 8> Reg rb;
  __OperandInfo
    InList<pg, ra, rb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, rb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<rb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode I2IP_RUR : [I2IP]
  __Encoding
    field<8, 4> SType stype==RUR;
    field<32, 6> UReg urb;
  __OperandInfo
    InList<pg, ra, urb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, urb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode I2IP_RIR : [I2IP]
  __Encoding
    field<8, 4> SType stype==RIR;
    field<32, 32> SImm32 vb;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOpcode I2IP_RCR : [I2IP]
  __Encoding
    field<8, 4> SType stype==RCR;
    field<32, 22> CMem vb;
  __OperandInfo
    InList<pg, ra, vb, rc>;
    OutList<rd>;
    Order<pg, rd, ra, vb, rc>;
    Bitwidth<ra> = 32;
    Bitwidth<vb> = 32;
    Bitwidth<rc> = 32;
    Bitwidth<rd> = 32;

__DefOptype R2UR : [IALU]
  __Encoding
    field<0,  8> Optype optype == R2UR;
    field<12,  3> Pred pg = PT;
    field<15,  1> PModi pg.not = False;
    field<16,  6> UReg urd;

  __Syntax
```asm          
R2UR URd, Rb      $sched $req $wsb ;
```

  __Description
将源寄存器Rb的值赋予目标寄存器URd。

  __OperandInfo
目的操作数URd必须来源于UR，源操作数Rb必须来源于GPR。

由于UR是warp内32线程公有，而GPR是每个线程私有，二者是一对多的关系，实际必须选择32个线程中某一个的GPR赋予给UR。

选择的机制是：根据当前warp的ActiveMask，以及各个线程的guard predicate的值，备选线程必须满足：

（1）ActiveMask对应bit为1

（2）该指令（R2UR）的guard predicate为true

从满足上述条件的备选线程中选择线程ID最小的一个，将它的GPR值赋予给UR。

  __Semantics
```asm
R2UR URd, Rb:
    // pgv表示当前warp的所有线程guard predicate组成的32bit mask
    // 选出源操作数Rb对应的线程ID
    laneId = pickLane(activeMask, pgv);
    // 将对应线程的Rb值赋予给URd
    URd = thread(laneId).Rb;
```

  __Examples
```asm
R2UR UR0, R0;
```

__DefOpcode R2UR_R : [R2UR]
  __Encoding
    field<8,   4> SType stype == R;
    field<32,  8> Reg rb;
  __OperandInfo
    InList<pg, rb>;
    OutList<urd>;
    Order<pg, urd, rb>;
    Bitwidth<rb> = 32;
    Bitwidth<urd> = 32;

__DefOptype SETGPR : [IALU]
  __Encoding
    field<0,  8> Optype optype == SETGPR;
    field<24, 8> Reg ra;

  __Syntax
```asm          
SETGPR R[URb{+SImm9}], Ra      $sched $req ;
```

  __Description
通过动态索引，而非GPR名，间接修改GPR的值，即R[URb+SImm9] = Ra。

  __OperandInfo
Ra必须来源于GPR，表示要赋予目的寄存器的值。

URb必须来源于UR，表示要修改的目的寄存器的索引值。

允许使用一个9bit的有符号立即数字面值SImm9，表示在URb基础上的偏移量。

如果要修改的GPR索引值超出硬件允许的单线程GPR范围，该指令会触发异常。

  __Semantics
```asm
SETGPR R[URb+SImm9], Ra:
    R[URb+SImm9] = Ra;
```

  __Examples
```asm
SETGPR R[UR2]    , R0;  // R[UR2] = R0，例如若UR2=0x2，则R2 = R0
SETGPR R[UR2+0x1], R1;  // R[UR2+1] = R1，例如若UR2=0x2，则R3 = R1
```

__DefOpcode SETGPR_U : [SETGPR]
  __Encoding
    field<8,  4> SType stype == U;
    field<64, 6> UReg urb;
    field<32, 9> SImm9 ridx;
  __OperandInfo
    InList<pg, ra, urb>;
    OutList<>;
    Order<pg, R[urb, ridx], ra>;
    Bitwidth<ra> = 32;
    Bitwidth<urb> = 32;

__DefOptype GETGPR : [IALU]
  __Encoding
    field<0,  8> Optype optype == GETGPR;
    field<16,  8> Reg rd;

  __Syntax
```asm          
GETGPR Rd, R[URb{+SImm9}]      $sched $req ;
```

  __Description
通过动态索引，而非GPR名，间接读取某个指定的GPR的值，即Rd = R[URb+SImm9]。

  __OperandInfo
Rd必须来源于GPR。

URb必须来源于UR，表示要读取的目的寄存器的索引值。

允许使用一个9bit的有符号立即数字面值SImm9，表示在URb基础上的偏移量。

如果要访问的GPR索引值超出硬件允许的单线程GPR范围，该指令将触发异常。

  __Semantics
```asm
GETGPR Rd, R[URb+SImm9]:
    Rd = R[URb+SImm9];
```

  __Examples
```asm
GETGPR R0, R[UR2];          // R0 = R[UR2]，例如若UR2 = 0x4，则R0 = R4
GETGPR R1, R[UR2+0x1];      // R1 = R[UR2+1]，例如若UR2 = 0x4，则R0 = R5
```

__DefOpcode GETGPR_U : [GETGPR]
  __Encoding
    field<8,  4> SType stype == U;
    field<64, 6> UReg urb;
    field<32, 9> SImm9 ridx;
  __OperandInfo
    InList<pg, urb>;
    OutList<rd>;
    Order<pg, rd, R[urb, ridx]>;
    Bitwidth<urb> = 32;
    Bitwidth<rd> = 32;